package de.arndt_panzer.bensgallery;

import java.io.File;
import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

public class GalleryImageAdapter extends BaseAdapter {

	public static final String TAG = GalleryImageAdapter.class.getSimpleName();
	private static final int PRELOAD_IMAGES = 2;

	private Context mContext;
	private String[] mImages;
	private int mWidth;
	private int mHeight;
	private BitmapWorkerTask mBitmapLoader;
	private UpdateImageAsyncTask mAsynFolderUpdate;

	public GalleryImageAdapter(Context context, int width, int height) {
		mContext = context;
		mImages = new String[0];
		mWidth = width;
		mHeight = height;
		requestImageUpdate();
	}

	public int getCount() {
		return mImages.length;
	}

	public String getItem(int position) {
		return mImages[position];
	}

	public long getItemId(int position) {
		return position;
	}

	// Override this method according to your need
	public View getView(int index, View view, ViewGroup viewGroup) {
		final RelativeLayout layoutView;
		String bitmapPath = (String) getItem(index);
		Bitmap bmp = null;
		ArrayList<BitmapWorkerParameter> params = new ArrayList<BitmapWorkerParameter>();

		// recycle view?
		if (view == null) {
			// no - make a new image view
			layoutView = (RelativeLayout) LayoutInflater.from(mContext)
					.inflate(R.layout.layout_gallery_imageview, viewGroup,
							false);
		} else
			// yes - reuse it
			layoutView = (RelativeLayout) view;

		// get sub items
		final ImageView imageView = (ImageView) layoutView
				.findViewById(R.id.imageView);
		final ImageView imagePlay = (ImageView) layoutView
				.findViewById(R.id.imageView_play);
		imagePlay.setVisibility(View.INVISIBLE);
		// remind the index position
		imageView.setTag(R.string.tag_key_index, Integer.valueOf(index));
		// set default visibility
		imageView.setVisibility(View.VISIBLE);
		// clear references
		imageView.setTag(R.string.tag_key_weakref, null);
		// initialize parameter
		BitmapWorkerParameter param = new BitmapWorkerParameter(bitmapPath,
				imageView, mWidth, mHeight, true);
		// check if view already initialized
		if (layoutView.getTag() == null
				|| !((String) layoutView.getTag()).equals(bitmapPath)) {
			// remind the bitmap path
			layoutView.setTag(bitmapPath);
			// check if image is in cache
			String imageCacheKey = BitmapWorkerTask.getBitmapKey(param);
			bmp = BitmapWorkerTask.getBitmapFromMemCache(imageCacheKey);
			// set image to view if cached
			if (bmp != null) {
				imageView.setImageBitmap(bmp);
				Log.d(TAG, "getView(): image in cache, position: " + index);
			}
		}
		// add this image to the task queue
		if (bmp == null) {
			// remind view
			params.add(param);
		}
		// show play button on videos
		if (BitmapHelper.isMovie(new File(bitmapPath)))
			imagePlay.setVisibility(View.VISIBLE);
		// load surrounding images
		for (int i = index - PRELOAD_IMAGES; i <= index + PRELOAD_IMAGES; ++i) {
			if (i >= 0 && i != index) {
				if (i + 1 < mImages.length) {
					String bmpPath = (String) getItem(i);
					if (!BitmapHelper.isMovie(new File(bmpPath))) {
						// collect loader task parameter - only for images
						final BitmapWorkerParameter p = new BitmapWorkerParameter(
								bmpPath, null, mWidth, mHeight, true);
						params.add(p);
					}
				} else
					break;
			} else
				continue;
		}
		// start loader task
		if (params.size() > 0) {
			// check loader state
			if (mBitmapLoader != null) {
				if (mBitmapLoader.getStatus() == AsyncTask.Status.RUNNING) {
					// interrupt
					mBitmapLoader.cancel(false);
					Log.d(TAG,
							"getView(): cancel bitmap loader task, position: "
									+ index);
				}

			}
			// create a new asynchronous loader task
			mBitmapLoader = new BitmapWorkerTask();
			mBitmapLoader.execute(params
					.toArray(new BitmapWorkerParameter[params.size()]));
		}
		return layoutView;
	}

	private class UpdateImageAsyncTask extends AsyncTask<File, Void, String[]> {

		@Override
		protected String[] doInBackground(File... params) {
			ArrayList<String> files = new ArrayList<String>();
			for (File f : params) {
				if (f.isFile() && BitmapHelper.isSupportedMedia(f)) {
					files.add(f.getAbsolutePath());
				} else if (f.isDirectory()) {
					File[] mediaFiles = f
							.listFiles(new BitmapHelper.MediaFileFilter());
					for (File mf : mediaFiles) {
						files.add(mf.getAbsolutePath());
					}
				}
			}
			return files.toArray(new String[files.size()]);
		}

		@Override
		protected void onPostExecute(String[] result) {
			GalleryImageAdapter.this.mImages = result;
			GalleryImageAdapter.this.notifyDataSetChanged();
		}

	}

	public void requestImageUpdate() {
		if (mAsynFolderUpdate != null
				&& mAsynFolderUpdate.getStatus() == AsyncTask.Status.RUNNING)
			return;
		if (Environment.getExternalStorageState().equalsIgnoreCase(
				Environment.MEDIA_MOUNTED)) {
			File root = Environment.getExternalStorageDirectory();
			File dcim = Environment
					.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
			mAsynFolderUpdate = new UpdateImageAsyncTask();
			mAsynFolderUpdate.execute(root, dcim);
		} else {
			Toast.makeText(mContext, "Keine Speicherkarte gefunden :-(",
					Toast.LENGTH_LONG).show();
		}

	}
}
